package com.code.ape.codeape.device.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义线程池
 * @author 公众号：码猿技术专栏   版权：不才陈某所署，侵权必究
 * @date 2022/5/20
 */
@Configuration
@Slf4j
public class QuartzTaskExecutorConfig {

	/**
	 * 获取当前机器的核数, 不一定准确 请根据实际场景 CPU密集 || IO 密集
	 */
	public static final int cpuNum = Runtime.getRuntime().availableProcessors();

	@Value("${thread.pool.corePoolSize:}")
	private Optional<Integer> corePoolSize;

	@Value("${thread.pool.maxPoolSize:}")
	private Optional<Integer> maxPoolSize;

	@Value("${thread.pool.queueCapacity:}")
	private Optional<Integer> queueCapacity;

	@Value("${thread.pool.awaitTerminationSeconds:}")
	private Optional<Integer> awaitTerminationSeconds;
	public final static String QUARTZ_THREAD_POOL_NAME="quartz_pool";


	@Bean(value = QuartzTaskExecutorConfig.QUARTZ_THREAD_POOL_NAME)
	public Executor quartzExecutor() {
		ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
		// 核心线程大小 默认区 CPU 数量
		taskExecutor.setCorePoolSize(corePoolSize.orElse(cpuNum)/2);
		// 最大线程大小 默认区 CPU * 2 数量
		taskExecutor.setMaxPoolSize(maxPoolSize.orElse(cpuNum * 2)/2);
		// 队列最大容量
		taskExecutor.setQueueCapacity(queueCapacity.orElse(500)/2);
		/**
		 * 拒绝策略，默认是AbortPolicy
		 * AbortPolicy：丢弃任务并抛出RejectedExecutionException异常
		 * DiscardPolicy：丢弃任务但不抛出异常
		 * DiscardOldestPolicy：丢弃最旧的处理程序，然后重试，如果执行器关闭，这时丢弃任务
		 * CallerRunsPolicy：执行器执行任务失败，则在策略回调方法中执行任务，如果执行器关闭，这时丢弃务
		 */
		taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
		taskExecutor.setAwaitTerminationSeconds(awaitTerminationSeconds.orElse(60));
		taskExecutor.setThreadNamePrefix("CodeApe-quartz-Thread-");
		taskExecutor.initialize();
		return taskExecutor;
	}
}
